iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Modern Web

用 Node.js 打造後端 API系列 第 11

Day 11 - 計算課程平均費用

  • 分享至 

  • xImage
  •  

前言


我們在Day 08建立了course model與bootcamp model的關係
對courses進行GET請求時,可以得到bootcamp的資料
而這次要做的功能是,對bootcamps資料進行GET請求時,利用mongoose的statics計算出該bootcamp對應的courses之平均tuition
計算後的平均tuition會以新欄位'averageCost'呈現

Statics


Statics與methods不同的地方在於,前者直接向model添加class methods
後者則是向document添加instance method
因為我們的目標是計算多筆courses資料的平均tuition是多少
所以可以在儲存course後與刪除course前,直接對全部的tuition進行計算

// 用 Static method 計算平均的course tuition
CourseSchema.statics.getAverageCost = async function(bootcampId) {
  const obj = await this.aggregate([
    {
      $match: { bootcamp: bootcampId }
    },
    {
      $group: {
        _id: '$bootcamp',
        averageCost: { $avg: '$tuition' }
      }
    }
  ]);

  try {
    await this.model('Bootcamp').findByIdAndUpdate(bootcampId, {
      averageCost: Math.ceil(obj[0].averageCost / 10) * 10
    });
  } catch(err) {
    console.error(err);
  }
}

利用mongoose aggregrate,先找到course對應到的bootcamp, 再利用$group將不同的bootcamp documents分成不同的group

// Call getAverageCost after save
CourseSchema.post('save', function() {
  this.constructor.getAverageCost(this.bootcamp);
});

// Call getAverageCost before remove
CourseSchema.pre('remove', function() {
  this.constructor.getAverageCost(this.bootcamp);
});

在儲存course前與刪除course資料後,對model呼叫getAverageCost,並傳入bootcampId
就能將averageCost儲存到bootcamp的資料中


上一篇
Day 10 - 完成Course CRUD功能
下一篇
Day 12 - 上傳照片
系列文
用 Node.js 打造後端 API30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言